package com.hsd.znsh.service.impl;

import com.hsd.znsh.converter.MonitorConverter;
import com.hsd.znsh.entity.Host;
import com.hsd.znsh.entity.Monitor;
import com.hsd.znsh.entity.User;
import com.hsd.znsh.enums.DeletedStatusEnum;
import com.hsd.znsh.enums.MonitorTypeEnum;
import com.hsd.znsh.enums.ResultEnum;
import com.hsd.znsh.exception.ZnshException;
import com.hsd.znsh.pojo.output.MonitorVO;
import com.hsd.znsh.pojo.query.MonitorQuery;
import com.hsd.znsh.repository.*;
import com.hsd.znsh.service.MonitorService;
import com.hsd.znsh.service.YsService;
import com.hsd.znsh.utils.*;
import com.hsd.znsh.vlc.VlcThread;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/*
 * @auther: wangjiacai
 *
 * @create: 2018-04-25 10:12:16
 */
@Service
public class MonitorServiceImpl extends BaseServiceImpl implements MonitorService {

    @Autowired
    private MonitorRepository monitorRepository;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private HostRepository hostRepository;

    @Autowired
    private UserMonitorRepository userMonitorRepository;

    @Autowired
    private YsService ysService;


    @Override
    public List<MonitorVO> getMonitorList(Pageable pageable, MonitorQuery monitorQuery,Integer userId) {
        if(userId!=null) monitorQuery.setCreateUserId(userId);
        List<Monitor> list=this.find(HqlUtil.getQueryHql(monitorQuery),monitorQuery,pageable);
        return MonitorConverter.converterToMonitorVOList(list,hostRepository,userRepository);
    }


    @Override
    public long getMonitorListTotalPages(MonitorQuery monitorQuery,Integer userId) {
        if(userId!=null) monitorQuery.setCreateUserId(userId);
        return this.count(HqlUtil.getCountHql(monitorQuery),monitorQuery);
    }

    @Override
    public MonitorVO getMonitorInfo(Integer id) {
        Monitor monitor=monitorRepository.findOne(id);
        return MonitorConverter.converterToMonitorVO(monitor,hostRepository,userRepository);
    }

    @Override
    public Monitor addMonitor(Monitor monitor) {
        validAddMonitor(monitor);
        if(SecurityUtil.hasRole("BACKGROUND_MANAGER")){
            monitor.setCreateUserId(SecurityUtil.getUserId());
        }
        monitor.setAlias(monitor.getProbeName());
        ysService.add(monitor);
        return monitorRepository.save(monitor);
    }

    @Override
    public Monitor updateMonitor(Monitor monitor) {
        validUpdateMonitor(monitor);
        Monitor target=monitorRepository.findOne(monitor.getId());
        BeanUtil.copyPropertiesIgnoreNull(monitor,target);
        if(SecurityUtil.hasRole("BACKGROUND_MANAGER")){
            target.setCreateUserId(SecurityUtil.getUserId());
        }
        return monitorRepository.save(target);
    }

    private void validAddMonitor(Monitor monitor){
        Monitor monitor1=monitorRepository.findByProbeName(monitor.getProbeName());
        if(monitor1!=null) throw new ZnshException(ResultEnum.PROBE_NAME_EXITS);

        Monitor monitor2=monitorRepository.findByProbeName(monitor.getMonitorSn());
        if(monitor2!=null) throw new ZnshException(ResultEnum.MONITOR_SN_EXITS);
    }

    private void validUpdateMonitor(Monitor monitor){
        Monitor monitor1=monitorRepository.findByProbeName(monitor.getProbeName());
        if(monitor1!=null&&monitor.getId()!=monitor1.getId()) throw new ZnshException(ResultEnum.PROBE_NAME_EXITS);

        Monitor monitor2=monitorRepository.findByProbeName(monitor.getMonitorSn());
        if(monitor2!=null&&monitor.getId()!=monitor2.getId()) throw new ZnshException(ResultEnum.MONITOR_SN_EXITS);
    }

    @Override
    public void deleteMonitor(Integer id) {
        ysService.delete(monitorRepository.findOne(id).getMonitorSn());
        userMonitorRepository.deleteByMonitorId(id);
        monitorRepository.delete(id);
    }

    @Override
    public List<Monitor> getQjMonitorList() {
        return monitorRepository.findByMonitorType(MonitorTypeEnum.QIANGJI.getCode());
    }

    @Override
    public List<Monitor> getUserQjMonitorList(Integer userId) {
        List<Integer> monitorIds=userMonitorRepository.findMonitorIdListByUserId(userId);
        return monitorRepository.findByMonitorTypeAndIdIn(MonitorTypeEnum.QIANGJI.getCode(),monitorIds);
    }

    @Override
    public List<Monitor> getUjMonitorList() {
        return monitorRepository.findByMonitorType(MonitorTypeEnum.QIUJI.getCode());
    }

    @Override
    public List<Monitor> getUserUjMonitorList(Integer userId) {
        List<Integer> monitorIds=userMonitorRepository.findMonitorIdListByUserId(userId);
        return monitorRepository.findByMonitorTypeAndIdIn(MonitorTypeEnum.QIUJI.getCode(),monitorIds);
    }

    @Override
    public Map generalUserAddress(Integer id,HttpServletRequest request) {
        Map<String,Object> map=new HashMap<>();
        Monitor monitor=monitorRepository.findOne(id);
        map.put("videoStreamAddress",VlcUtil.getVideoStreamAddress(request.getServletContext(),monitor));
        return map;
    }

    @Override
    public Map vipOrManagerAddress(Integer id) {
        if(!SecurityUtil.hasRole("ROLE_VIP")&&!SecurityUtil.hasRole("ROLE_PC_MANAGER")){
            throw new ZnshException(ResultEnum.ILLEGAL_USERS);
        }
        Map<String,Object> map=new HashMap<>();
        Monitor monitor=monitorRepository.findOne(id);
        map.put("iframeAddress",monitor.getLine()+":"+monitor.getNvr());
        return map;
    }

    @Override
    public List<Monitor> getMonitorListByHostSn(String hostSn) {
        Host host=hostRepository.findByHostSn(hostSn);
        return monitorRepository.findByHostId(host.getId());
    }

    @Override
    public List<MonitorVO> getMonitorListByAppUser(User user) {
        User manager=userRepository.findOne(user.getCreateUserId());
        List<Monitor> list=monitorRepository.findByCreateUserId(manager.getId());
        return MonitorConverter.converterToMonitorVOList(list,hostRepository,userRepository);
    }

    @Override
    public Monitor assignMonitor(String monitorSn, String alias, String hostSn) {
        Host host=hostRepository.findByHostSn(hostSn);
        Monitor monitor=monitorRepository.findByMonitorSn(monitorSn);
        monitor.setAlias(alias);
        monitor.setHostId(host.getId());
        return monitorRepository.save(monitor);
    }

    @Override
    public Monitor unbindMonitor(String monitorSn) {
        Monitor monitor=monitorRepository.findByMonitorSn(monitorSn);
        monitor.setHostId(null);
        return monitorRepository.save(monitor);
    }

    @Override
    public long countMonitorByHostSn(String hostSn) {
        Host host=hostRepository.findByHostSn(hostSn);
        return monitorRepository.countByHostId(host.getId());
    }
}
